package be.sc.classicnetwork.controller.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.Authentication;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import be.sc.classicnetwork.model.User;
import be.sc.classicnetwork.model.UserInfo;
import be.sc.classicnetwork.model.UserLog;
import be.sc.classicnetwork.service.ServiceLocator;
import be.sc.classicnetwork.util.RequestAttributeConstant;
import be.sc.classicnetwork.util.RoleConstant;

/**
 * ApplicationInterceptor.
 */
public class AuditInterceptor extends HandlerInterceptorAdapter {

    private LocaleResolver localeResolver;
    private ServiceLocator serviceLocator;

    /**
     * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#preHandle(javax.servlet.http.HttpServletRequest,
     *      javax.servlet.http.HttpServletResponse, java.lang.Object)
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
	// get the Authentication
	Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
	User user;

	// check anonymous access
	if (authentication.getName().equals("roleAnonymous")) {
	    user = User.ANONYMOUS_USER;
	} else {
	    user = (User) authentication.getPrincipal();
	}

	// set the current user
	User.setCurrentUser(user);

	// fill user info for logging purpose
	UserInfo userInfo = new UserInfo();
	UserLog userLog = new UserLog();
	userLog.setUserInfo(userInfo);
	userLog.setUrl(request.getRequestURL().toString());
	userLog.setSessionId(request.getSession().getId());

	userInfo.setRemoteAddress(request.getRemoteAddr());
	userInfo.setRemoteHost(request.getRemoteHost());
	userInfo.setRemotePort(request.getRemotePort());
	userInfo.setRemoteUser(user.getUsername());
	userInfo.setUserAgent(request.getHeader("user-agent"));
	user.setUserInfo(userInfo);

	// set the UserLog as request attribute for further log in any
	// Controller
	request.setAttribute(RequestAttributeConstant.USER_LOG, userLog);

	// points to the right collection of cars
	request.setAttribute(RequestAttributeConstant.CARS,
		user.isInRole(RoleConstant.ROLE_SUB_ADMIN) ? RequestAttributeConstant.ALL_CARS
			: RequestAttributeConstant.FILTERED_CARS);

	// set the locale
	user.setLocale(localeResolver.resolveLocale(request));

	return true;
    }

    /**
     * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#afterCompletion(javax.servlet.http.HttpServletRequest,
     *      javax.servlet.http.HttpServletResponse, java.lang.Object,
     *      java.lang.Exception)
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
	    throws Exception {
	// save the UserLog info
	UserLog userLog = (UserLog) request.getAttribute(RequestAttributeConstant.USER_LOG);
	if (userLog != null && userLog.isPersistable()) {
	    this.serviceLocator.getCarService().saveOrUpdateAny(userLog);
	}
    }

    public void setLocaleResolver(LocaleResolver localeResolver) {
	this.localeResolver = localeResolver;
    }

    public void setServiceLocator(ServiceLocator serviceLocator) {
	this.serviceLocator = serviceLocator;
    }

}
